home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / I.h < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-20  |  6.9 KB  |  235 lines

  1. /*
  2.  * I.h -  support for invariants (assertions) using C code.
  3.  *
  4.  * Copyright (c) 1997 Phil Maker
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  *
  16.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26.  * SUCH DAMAGE.
  27.  *
  28.  * Id: I.h,v 1.1.1.1 1997/11/23 11:45:50 pjm Exp 
  29.  */
  30.  
  31.  
  32. #ifndef _I_h_
  33. #define _I_h_ 1
  34.  
  35. #ifdef __cplusplus
  36. extern "C" {
  37. #endif
  38.  
  39. #ifndef WITHOUT_NANA
  40.  
  41. /*
  42.  * nana-config.h - the system wide configuration file; we put the ifndef
  43.  *   around it to avoid the file 5 million times during a compile.
  44.  */
  45.  
  46. #ifndef _nana_config_h_
  47. #include <nana-config.h>
  48. #endif
  49.  
  50. /* 
  51.  * I_LEVEL sets the level of invariant analogously to NDEBUG in assert.h
  52.  *
  53.  *   I_LEVEL == 2: invariants are always evaluated.
  54.  *   I_LEVEL == 1: evaluate invariants iff they have a true GUARD.
  55.  *   I_LEVEL == 0: invariants are never evaluated.
  56.  */
  57.  
  58. #ifndef I_LEVEL /* define DEFAULT for I_LEVEL */
  59. #define I_LEVEL 1
  60. #endif
  61.  
  62.  
  63. /*
  64.  * I_DEFAULT_GUARD - the default guard expression; an invariant is checked
  65.  *     iff the guard is true. By default its always true.
  66.  */
  67.  
  68. #ifndef I_DEFAULT_GUARD
  69. #define I_DEFAULT_GUARD (1)
  70. #endif
  71.  
  72. /*
  73.  * I_DEFAULT_PARAMS - the default value to be passed as the second argument
  74.  *       to the handler macro when an invariant fails.
  75.  */
  76.  
  77.  
  78. #ifndef I_DEFAULT_PARAMS
  79. #define I_DEFAULT_PARAMS /* nothing */
  80. #endif
  81.  
  82. /*
  83.  * I_DEFAULT_HANDLER(expr,file,line,param) - called when an error is detected.
  84.  */
  85.  
  86. #ifndef I_DEFAULT_HANDLER /* define default handler */
  87. void _I_default_handler(char *expr, char *file, int line);
  88.  
  89. #define I_DEFAULT_HANDLER(expr,file,line,param) \
  90.   _I_default_handler(expr,__FILE__,__LINE__)
  91.  
  92. #endif /* I_DEFAULT_HANDLER */
  93.  
  94. /*
  95.  * _IGHPS(e,g,h,p,s) - implements the general case for invariant handling.
  96.  *
  97.  * e - expression to check
  98.  * g - guard, check only if this is true (subject to I_DEFAULT_LEVEL)
  99.  * h - handler, called when a failure is detected
  100.  * p - parameter to pass off to the handler
  101.  * s - string representation of the expression (e.g. "I(x>=i)")
  102.  *
  103.  * _ISD(e) - generates a data declaration for use in postconditions
  104.  * _ISG(e,g) - generates a guarded assignment to a data declaration
  105.  *     for use in postconditions
  106.  *
  107.  *     N.B. The two types are necessary since we cannot guard a C declaration
  108.  *     with an if statement.
  109.  */
  110.  
  111. #if I_LEVEL == 2 /* always check the assertion */
  112. #define _IGHPS(e,g,h,p,s) \
  113.     do { \
  114.         if(!(e)) { \
  115.             h (s, __FILE__, __LINE__, p); \
  116.         } \
  117.     } while(0)
  118.  
  119. #define _ID(e) e
  120. #define _ISG(e,g) e
  121. #elif I_LEVEL == 1 /* check it iff g is true */
  122. #define _IGHPS(e,g,h,p,s) \
  123.     do { \
  124.         if(g) { \
  125.             if(!(e)) { \
  126.                 h (s, __FILE__, __LINE__, p); \
  127.             } \
  128.         } \
  129.     } while(0)
  130. #define _ID(e) e
  131. #define _ISG(e,g) \
  132.         do { \
  133.         if(g) { \
  134.             e; \
  135.         } \
  136.     } while(0)
  137. #elif I_LEVEL == 0 /* no assertions so just remove them */
  138. #define _IGHPS(e,g,h,p,s) /* nothing */
  139. #define _ID(e) /* nothing */
  140. #define _ISG(e,g) /* nothing */
  141. #endif /* I_LEVEL */
  142.  
  143. /*
  144.  * And all the user macros; these are used to put in the default arguments.
  145.  * The name is used to determine the arguments; e.g. IGH takes an expression
  146.  * to check; a guard and a handler as parameters. The letters in the names
  147.  * are in ascending order (i.e. IGH(...) not IHG(...)).
  148.  *
  149.  * I[G][H][P] - it must be true (e) with an optional guard, handler and 
  150.  *    parameter for the handler.
  151.  * N[G][H][P] - as for I... except that (e) must never ever be true.
  152.  */
  153.  
  154. #define I(e) \
  155.   _IGHPS(e,I_DEFAULT_GUARD,I_DEFAULT_HANDLER,I_DEFAULT_PARAMS,"I("#e")")
  156. #define IG(e,g) \
  157.   _IGHPS(e,g,I_DEFAULT_HANDLER,I_DEFAULT_PARAMS,"I("#e")")
  158. #define IH(e,h) \
  159.   _IGHPS(e,I_DEFAULT_GUARD,h,I_DEFAULT_PARAMS,"I("#e")")
  160. #define IP(e,p) \
  161.   _IGHPS(e,I_DEFAULT_GUARD,I_DEFAULT_HANDLER,p,"I("#e")")
  162. #define IGH(e,g,h) \
  163.   _IGHPS(e,g,h,I_DEFAULT_PARAMS,"I("#e")")
  164. #define IGP(e,g,p) \
  165.   _IGHPS(e,g,I_DEFAULT_HANDLER,p,"I("#e")")
  166. #define IHP(e,h,p) \
  167.   _IGHPS(e,I_DEFAULT_GUARD,h,p,"I("#e")")
  168. #define IGHP(e,g,h,p) \
  169.   _IGHPS(e,g,h,p,"I("#e")")
  170.  
  171. #define N(e) \
  172.   _IGHPS((!(e)),I_DEFAULT_GUARD,I_DEFAULT_HANDLER,I_DEFAULT_PARAMS,"N("#e")")
  173. #define NG(e,g) \
  174.   _IGHPS((!(e)),g,I_DEFAULT_HANDLER,I_DEFAULT_PARAMS,"N("#e")")
  175. #define NH(e,h) \
  176.   _IGHPS((!(e)),I_DEFAULT_GUARD,h,I_DEFAULT_PARAMS,"N("#e")")
  177. #define NP(e,p) \
  178.   _IGHPS((!(e)),I_DEFAULT_GUARD,I_DEFAULT_HANDLER,p,"N("#e")")
  179. #define NGH(e,g,h) \
  180.   _IGHPS((!(e)),g,h,I_DEFAULT_PARAMS,"N("#e")")
  181. #define NGP(e,g,p) \
  182.   _IGHPS((!(e)),g,I_DEFAULT_HANDLER,p,"N("#e")")
  183. #define NHP(e,h,p) \
  184.   _IGHPS((!(e)),I_DEFAULT_GUARD,h,p,"N("#e")")
  185. #define NGHP(e,g,h,p) \
  186.   _IGHPS((!(e)),g,h,p,"N("#e")")
  187.  
  188. /*
  189.  * ID(e) - declares a variable to be used to store values for a postcondition.
  190.  *        This can include an initialiser. 
  191.  *        Note this declaration is not disabled by I_DEFAULT_GUARD
  192.  * IS(e) - an assignment to a variable. This statement is enabled by 
  193.  *        I_DEFAULT_GUARD
  194.  * ISG(e,g) - the guarded version of IS
  195.  */
  196.  
  197. #define ID(e) _ID(e)
  198. #define IS(e) _ISG(e,I_DEFAULT_GUARD)
  199. #define ISG(e,g) _ISG(e,g)
  200.  
  201. #else /* defined(WITHOUT_NANA) */
  202.  
  203. #define I(e) /* empty */
  204. #define IG(e,g) /* empty */
  205. #define IH(e,h) /* empty */
  206. #define IP(e,p) /* empty */
  207. #define IGH(e,g,h) /* empty */
  208. #define IGP(e,g,p) /* empty */
  209. #define IHP(e,h,p) /* empty */
  210. #define IGHP(e,g,h,p) /* empty */
  211.  
  212. #define N(e) /* empty */
  213. #define NG(e,g) /* empty */
  214. #define NH(e,h) /* empty */
  215. #define NP(e,p) /* empty */
  216. #define NGH(e,g,h) /* empty */
  217. #define NGP(e,g,p) /* empty */
  218. #define NHP(e,h,p) /* empty */
  219. #define NGHP(e,g,h,p) /* empty */
  220.  
  221. #define ID(e) /* empty */
  222. #define IS(e) /* empty */
  223. #define ISG(e,g) /* empty */
  224.  
  225. #endif /* !defined(WITHOUT_NANA) */
  226.  
  227. #ifdef __cplusplus
  228. }
  229. #endif
  230.  
  231. #endif /* _I_h_ */
  232.  
  233.  
  234.  
  235.